#include "../head.h"

/*图片操作模块*/


//图片放缩倍数
double scale_val[7] = {0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6};

//图片展示
char album[3][200] = {
    "img/C1.bmp",
    "img/C2.bmp",
    "img/C3.bmp",
};

//手动模式
void photo_mode_manual()
{
    int pos = 0;
    int n = 3;
    struct cor p;
    show_bmp(0, 0, album[0]);

    show_bmp(0, 420, "death/photo_return.bmp");     //60*60     //返回
    show_bmp(250, 430, "death/photo_reduce.bmp");     //50*50     //缩小
    show_bmp(500, 430, "death/photo_magnify.bmp");     //50*50     //放大
    show_bmp(740, 420, "death/photo_refresh.bmp");     //60*60      //刷新  
    

    while (1)
    {
        // print_my_name();
        switch (get_direction())
        {
        case LEFT:
            n  = 3;
            pos = (pos + 1) % 3;
            printf("left\n");
            if (show_bmp_with_blinds(0, 0, album[pos], 100, 500, LEFT) == -1)
                printf("显示错误！\n");
            break;
        case RIGHT:
            n = 3;
            printf("right\n");
            pos = (pos - 1 + 3) % 3;
            if (show_bmp_with_blinds(0, 0, album[pos], 100, 500, RIGHT) == -1)
                printf("显示错误！\n");
                
            break;
        case ADD:
        {
            if (n < 6)
                n++;
            p = calculate_top_left_corner(800, 480, scale_val[n], scale_val[n]);
            show_bmp_scaled(p.x, p.y, album[pos], scale_val[n], scale_val[n]);
               
            break;
        }
        case DES:
        {
            if (n > 0)
                n--;
                show_a_color(0);
            p = calculate_top_left_corner(800, 480, scale_val[n], scale_val[n]);
            show_bmp_scaled(p.x, p.y, album[pos], scale_val[n], scale_val[n]);
        
            break;
        }
        case REFRESH:
        {
            show_bmp(0,0,album[pos]);
            break;
        }
        case EXIT:
            return;
        }
        
            

        show_bmp(0, 420, "death/photo_return.bmp");     //60*60     //返回
        show_bmp(250, 430, "death/photo_reduce.bmp");     //50*50     //缩小
        show_bmp(500, 430, "death/photo_magnify.bmp");     //50*50     //放大
        show_bmp(740, 420, "death/photo_refresh.bmp");     //60*60      //刷新 
    }
}


//自动模式
void photo_mode_auto()
{
    int pos = 0;
    int n = 3;
    struct cor p;
    show_bmp(0, 0, album[0]);
    while (pos < 3)
    {
        pos++;
        printf("left\n");
        if (show_bmp_with_blinds(0, 0, album[pos], 100, 1500, LEFT) == -1)
            printf("显示错误！\n");
    }
}


//返回键，关闭音乐
void photopage_return(void)
{
    system("pkill -9 madplay");
}


//滑动特效
int show_bmp_with_blinds(int x0, int y0, char *filename, int strip_width, int delay_us, int direction)
{
    int fd = open(filename, O_RDWR);
    if (fd == -1)
    {
        perror("OPEN ERROR");
        return -1;
    }

    int width = 0, height = 0;
    int depth = 0;
    if (lseek(fd, 0x12, SEEK_SET) == -1 || read(fd, &width, 4) != 4 || lseek(fd, 0x16, SEEK_SET) == -1 || read(fd, &height, 4) != 4 || lseek(fd, 0x1c, SEEK_SET) == -1 || read(fd, &depth, 4) != 4)
    {
        perror("Read ERROR");
        close(fd);
        return -1;
    }

    int laizi = 0;     // 表示要填充的字节数
    int line_size = 0; // 实际的字节数
    laizi = 4 - (abs(width) * (depth / 8)) % 4;
    if (laizi == 4)
    {
        laizi = 0;
    }

    line_size = abs(width) * (depth / 8) + laizi;
    unsigned char buf[abs(height) * line_size];
    if (lseek(fd, 0x36, SEEK_SET) == -1 || read(fd, buf, abs(height) * line_size) != abs(height) * line_size)
    {
        perror(" Read(1) ERROR");
        close(fd);
        return -1;
    }

    unsigned b, g, r, a = 0;
    int i, j, k;
    int num;
    int color;

    int num_segments = (abs(width) + strip_width - 1) / strip_width; // 计算条块数量

    // 开始从左到右或从右到左同时显示8块
    for (i = 0; i < abs(width); i++) // 控制水平显示，从左到右/右到左移动
    {
        for (k = 0; k < num_segments; k++) // 对每块同时显示
        {
            for (j = 0; j < abs(height); j++) // 每块中的每行
            {
                if (direction == RIGHT) // 从左到右
                {
                    if (k * strip_width <= i && i < (k + 1) * strip_width) // 仅在当前条块内显示
                    {
                        num = j * line_size + i * (depth / 8);
                        b = buf[num++];
                        g = buf[num++];
                        r = buf[num++];
                        if (depth == 32)
                        {
                            a = buf[num++];
                        }
                        color = (a << 24) | (r << 16) | (g << 8) | b;

                        // 绘制该像素
                        display_point(x0 + i, y0 + (height > 0 ? abs(height) - 1 - j : j), color);
                    }
                }
                else if (direction == LEFT) // 从右到左
                {
                    if (k * strip_width <= (abs(width) - 1 - i) && (abs(width) - 1 - i) < (k + 1) * strip_width) // 仅在当前条块内显示
                    {
                        num = j * line_size + (abs(width) - 1 - i) * (depth / 8);
                        b = buf[num++];
                        g = buf[num++];
                        r = buf[num++];
                        if (depth == 32)
                        {
                            a = buf[num++];
                        }
                        color = (a << 24) | (r << 16) | (g << 8) | b;

                        // 绘制该像素
                        display_point(x0 + (abs(width) - 1 - i), y0 + (height > 0 ? abs(height) - 1 - j : j), color);
                    }
                }
            }
        }

        usleep(delay_us); // 控制移动速度，形成滑动效果
    }

    // 关闭文件
    close(fd);
    return 0;
}


//图片放缩
struct cor calculate_top_left_corner(int width, int height, float scale_x, float scale_y)
{
    struct cor result;

    // 计算目标缩放后的尺寸
    int dst_width = width * scale_x;
    int dst_height = height * scale_y;

    // 计算屏幕中心
    int screen_width = 800;
    int screen_height = 480;
    int screen_center_x = screen_width / 2;
    int screen_center_y = screen_height / 2;

    // 计算图像中心
    int image_center_x = dst_width / 2;
    int image_center_y = dst_height / 2;

    // 计算左上角坐标
    result.x = screen_center_x - image_center_x;
    result.y = screen_center_y - image_center_y;

    // 确保坐标不越界
    if (result.x < 0)
    {
        result.x = 0;
    }
    if (result.y < 0)
    {
        result.y = 0;
    }
    if (result.x + dst_width > screen_width)
    {
        result.x = screen_width - dst_width;
    }
    if (result.y + dst_height > screen_height)
    {
        result.y = screen_height - dst_height;
    }

    return result;
}


//显示放缩后的图片
int show_bmp_scaled(int x0, int y0, char *filename, float scale_x, float scale_y)

{
    int fd = open(filename, O_RDWR);
    if (fd == -1)
    {
        perror("OPEN ERROR");
        return -1;
    }

    int width = 0, height = 0;
    int depth = 0;
    if (lseek(fd, 0x12, SEEK_SET) == -1 || read(fd, &width, 4) != 4 || lseek(fd, 0x16, SEEK_SET) == -1 || read(fd, &height, 4) != 4 || lseek(fd, 0x1c, SEEK_SET) == -1 || read(fd, &depth, 4) != 4)
    {
        perror("Read ERROR");
        close(fd);
        return -1;
    }

    int laizi = 0;     // 表示要填充的字节数
    int line_size = 0; // 实际的字节数
    laizi = 4 - (abs(width) * (depth / 8)) % 4;
    if (laizi == 4)
    {
        laizi = 0;
    }

    line_size = abs(width) * (depth / 8) + laizi;
    unsigned char buf[abs(height) * line_size];
    if (lseek(fd, 0x36, SEEK_SET) == -1 || read(fd, buf, abs(height) * line_size) != abs(height) * line_size)
    {
        perror(" Read(1) ERROR");
        close(fd);
        return -1;
    }

    // 计算目标缩放后的尺寸
    int dst_width = abs(width) * scale_x;
    int dst_height = abs(height) * scale_y;

    unsigned b, g, r, a = 0;
    int src_i, src_j;
    int i, j;
    int num, src_num;
    int color;

    // 遍历缩放后的目标图像
    for (j = 0; j < dst_height; j++)
    {
        for (i = 0; i < dst_width; i++)
        {
            // 计算目标图像点对应的原始图像位置
            src_i = i / scale_x;
            src_j = j / scale_y;

            // 计算原图像中的索引位置
            src_num = (src_j * line_size) + (src_i * (depth / 8));

            // 读取原图像中的颜色值
            b = buf[src_num++];
            g = buf[src_num++];
            r = buf[src_num++];
            if (depth == 32)
            {
                a = buf[src_num++];
            }
            color = (a << 24) | (r << 16) | (g << 8) | b;

            // 绘制目标点
            display_point(x0 + i, y0 + j, color);
        }
    }

    // 关闭图片文件
    close(fd);
    return 0;
}